// Application of function overloading
// Created by Administrator on 2025/6/12.
//

#include <iostream>
#include <vector>
using namespace std;

/**
 * 方法重载
 * 方法名称相同，参数的类型、个数、顺序不同，根据参数的特性去匹配方法
 */
class PrintData {
public:
    // print function overloading
    void print(int i) {
        cout << "int value is:" << i << endl;
    }

    void print(double d) {
        cout << "double value is:" << d << endl;
    }

    void print(char f[]) {
        cout << "float value is:" << f << endl;
    }
};

// int main(int argc, char *argv[]) {
//     PrintData printData;
//
//     // call int print
//     printData.print(41);
//     // call double print
//     printData.print(20.15);
//     // call string print
//     printData.print("111");
// }


/**
 * C++中运算符重载
 *
 * 不可以重载的运算符有：
 *
 * .：成员访问运算符
 * .*, ->*：成员指针访问运算符
 * ::：域运算符
 * sizeof：长度运算符
 * ?:：条件运算符
 * #： 预处理符号
 *
 */
class Box {
    int width;
    int length;
    int height;

public:
    Box() { ; }
    Box(int w, int l, int h): width(w), length(l), height(h) { ; }

    /**
     * 一元运算符
     * 只需使用到一个参数
     */

    // 取反
    void operator -() {
        this->width = -this->width;
        this->height = -this->height;
        this->length = -this->length;
    }

    // ++ box
    Box operator ++() {
        cerr << "first ++" << endl;
        ++width;
        ++height;
        ++length;
        return *this;
    }

    // box ++
    Box operator ++(int) {
        Box box = *this;
        // 这里会调用上面定义的++前缀函数，可以看做成：++width;++height;++length;
        ++*this;
        return box;
    }

    /**
     * 二元运算符
     *  需要使用到两个参数
     */

    // 对 + 号进行重载，每次使用 + 号都会调用此方法
    Box operator +(const Box b) {
        Box box;
        box.width = this->width + b.width;
        box.length = this->length + b.length;
        box.height = this->height + b.height;
        return box;
    }

    // 相减
    Box operator -(const Box b) {
        Box box;
        box.width = this->width - b.width;
        box.length = this->length - b.length;
        box.height = this->height - b.height;
        return box;
    }

    // + 、 - 、 * 、 / 类似

    // 非成员函数的方式重载运算符 *
    // 友元函数必须先在类中声明或定义
    friend Box operator *(const Box b1, const Box b2);


    /**
     * 关系运算符
     *
     */
    bool operator <(const Box b) {
        return getSum() < b.getSum();
    }

    /**
     *  输入/输出运算符重载
     *
     */
    friend ostream &operator <<(ostream &out, const Box &b);

    friend istream &operator >>(istream &in, Box &b);

    void print() const {
        cout << "width: " << width << endl;
        cout << "length: " << length << endl;
        cout << "height: " << height << endl;
    }

    int getSum() const {
        return width + height + length;
    }
};

Box operator *(const Box b1, const Box b2) {
    Box box;
    box.width = b1.width * b2.width;
    box.length = b1.length * b2.length;
    box.height = b1.height * b2.height;
    return box;
}

ostream &operator <<(ostream &out, const Box &b) {
    out << "width:" << b.width << "\theight:" << b.height << "\tlength:" << b.length << endl;
    return out;
}

istream &operator >>(istream &in, Box &b) {
    in >> b.width >> b.height >> b.length;
    return in;
}

// int main(int argc, char *argv[]) {
//     Box box1(1, 1, 1);
//     Box box2(2, 2, 2);
//
//     // 相加
//     Box box3 = box1 + box2;
//     cout << "相加" << endl;
//     box3.print();
//
//     // 相减
//     cout << "相减" << endl;
//     Box box4 = box3 - box1;
//     box4.print();
//
//     // 先自增
//     cout << "先++" << endl;
//     Box box5 = ++box1;
//     box5.print();
//
//     // 后自增
//     cout << "后++" << endl;
//     Box box6 = box1++;
//     box6.print();
//     cout << endl;
//     box1.print();
//
//     // 取反
//     -box3;
//     cout << "取反" << endl;
//     box3.print();
//
//     Box box7(2, 2, 2);
//     Box box8(5, 3, 2);
//
//     // 相乘
//     cout << "相乘" << endl;
//     Box box9 = box7 * box8;
//     box9.print();
//
//     // 比较
//     bool isLt = box9 < box8;
//     cout << "box9 is lt box8 : " << isLt << endl;
//
//     // 输入/输出 重载
//     cout << "输入/输出重载" << endl;
//     cout << box9 << endl; // 输出： width:10	height:4	length:6
//
//     Box box10;
//     cin >> box10;
//     cout << box10 << endl;
// }


/**
 * 下面通过一个时钟示例，来加深理解
 *
 */
class Time {
private:
    int hours; // 小时，0-23
    int minutes; // 分钟，0-59
public:
    Time() {
        hours = 0;
        minutes = 0;
    }

    Time(int h, int m) {
        hours = h;
        minutes = m;
    }

    void print() {
        cout << "hours:" << hours << "\tminutes:" << minutes << endl;
    }

    // 重载前缀递增运算符 ++num
    Time operator ++() {
        ++minutes;
        if (minutes >= 60) {
            minutes = 0;
            ++hours;
        }
        return Time(hours, minutes);
    }

    // 重载后置递增运算符 num++
    // int 在括号内是为了向编译器说明这是一个后缀形式，而不是表示整数
    Time operator ++(int) {
        Time time(hours, minutes);
        ++minutes;
        if (minutes >= 60) {
            minutes = 0;
            ++hours;
        }
        return time;
    }
};

// int main(int argc, char *argv[]) {
//     Time t1(11,59);
//     Time t2(10,40);
//
//     ++t1;
//     t1.print();
//
//     ++t1;
//     t1.print();
//
//     t2++;
//     t2.print();
//
//     t2++;
//     t2.print();
//     return 0;
// }

class Check {
    int i;

public:
    Check() { ; }
    Check(int i): i(i = 0) { ; }

    // 前缀运算符
    Check operator ++() {
        Check temp;
        temp.i = ++i;
        return temp;
    }

    // 后缀运算符。形参是个int则表示是后缀运算（这个形参用不到，只是用来区分前缀和后缀）
    Check operator ++(int) {
        Check temp;
        temp.i = i++;
        return temp;
    }

    void print(void) const {
        cout << "Check i is :" << i << endl;
    }
};

// int main(int argc, char *argv[]) {
//     Check obj1(0), obj2(0);
//     obj1.print(); // 0
//     obj2.print(); // 0
//
//     obj2 = ++obj1; // 先调用函数运算，再赋值给obj2
//     obj1.print(); // 1
//     obj2.print(); // 1
//
//     obj2 = obj1++; // 先将值赋给obj2，再调用函数运算
//     obj1.print(); // 2
//     obj2.print(); // 1
// }


/**
 * C++赋值运算符
 * =
 *
 */
class Orange {
    string color;
    int weight;
    int taste;

public:
    Orange(string color, int weight, int taste): color(color), weight(weight), taste(taste) { ; }

    string getColor() const {
        return color;
    }

    int getWeight() const {
        return weight;
    }

    int getTaste() const {
        return taste;
    }

    void print() {
        cout << "color:" << color << "\tweight:" << weight << "\ttaste:" << taste << endl;
    }
};

class Apple {
    string color;
    int weight;
    int taste;

public:
    void operator =(const Orange orange) {
        color = orange.getColor();
        weight = orange.getWeight();
        taste = orange.getTaste();
    }

    void print() {
        cout << "color:" << color << "\tweight:" << weight << "\ttaste:" << taste << endl;
    }
};

// int main(int argc, char *argv[]) {
//     Orange orange("yellow", 100, 10);
//     Apple apple;
//     apple = orange; // 调用上面定义的赋值运算符
//     cout << "orange:\t";
//     orange.print();
//     cout << "apple:\t";
//     apple.print();
// }

/***
 * 函数调用运算符重载
 *
 */
class Distance {
private:
    int feet;
    int inches;

public:
    Distance() {
        feet = 0;
        inches = 0;
    }

    Distance(int f = 0, int i = 0) {
        feet = f;
        inches = i;
    }

    Distance operator()(int f, int i, int c) {
        feet = f + c;
        inches = i + c;
        return *this;
    }

    void print() const {
        cout << feet << "\'-" << inches << "\"" << endl;
    }
};

// int main(int argc, char *argv[]) {
//     Distance distance1(5, 8);
//     distance1.print();
//
//     Distance distance2(1,1);
//     distance2(5, 8, 10);
//     distance2.print();
// }


const short int SIZE_ = 10;

/**
 * 下标运算符重载
 *
 */

class Safearay {
    int arr[SIZE_];

public:
    Safearay() {
        for (int i = 0; i < SIZE_; ++i) {
            arr[i] = i;
        }
    }

    int operator [](int i) {
        if (i < 0) {
            cerr << "error index lt 0，current value: " << i << endl;
            return arr[0];
        }
        if (i >= SIZE_) {
            cerr << "error index gt max length，current value：" << i << endl;
            return arr[SIZE_ - 1];
        }
        return arr[i];
    }
};

// int main(int argc, char *argv[]) {
//     Safearay safearay;
//     cout << "value of A[-1] is:" << safearay[-1] << endl;
//     cout << "value of A[1] is:" << safearay[1] << endl;
//     cout << "value of A[7] is:" << safearay[7] << endl;
//     cout << "value of A[11] is:" << safearay[11] << endl;
// }


class Obj {
    static int i, j;

public:
    void f() const {
        cout << "i : " << i++ << endl;
    }

    void g() const {
        cout << "j : " << j++ << endl;
    }
};

int Obj::i = 10;
int Obj::j = 12;


// 定义一个容器类
class ObjContainer {
    vector<Obj *> a;

public :
    void add(Obj *obj) {
        a.push_back(obj);
    }

    friend class SmartPointer;
};

// 实现智能指针，用于访问类的 obj 的成员
class SmartPointer {
    ObjContainer oc; // 容器中装着10个数组元素
    int index;

public:
    SmartPointer(ObjContainer &objc) {
        oc = objc;
        index = 0;
    }

    // 返回值表示列表结束
    bool operator ++() {
        // 前缀++
        if (index >= oc.a.size() - 1) return false;
        if (oc.a[++index] == nullptr) return false;
        return true;
    }

    bool operator ++(int) {
        // 后缀++
        return operator++();
    }

    // 重载运算符 ->
    Obj *operator ->() const {
        if (!oc.a[index]) {
            cout << "Zero value" << endl;
            return (Obj *) 0;
        }
        return oc.a[index];
    }
};


int main(int argc, char *argv[]) {
    const int sz = 10;
    Obj o[sz]; // 初始化一个长度为10的数组
    ObjContainer oc; // 初始化容器
    for (int i = 0; i < sz; i++) {
        oc.add(&o[i]); // 将数组中的元素添加到容器中
    }
    SmartPointer sp(oc);
    do {
        sp->f(); // -> 返回的是 Obj 对象，所以可以调用成员函数
        sp->g();
    } while (sp++); // sp ++ 返回一个布尔值，当数组越界时返回 false，结束循环
    return 0;
}
